package UILayer;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Scanner;

/**
 * Write a description of class LeaseUI here.
 * 
 * @author (your name)
 * @version (a version number or a date)
 */
public class LeaseUI
{
	LeaseCtr lease_ctr;

	/**
	 * Constructor for objects of class LeaseUI
	 */
	public LeaseUI()
	{
		lease_ctr = new LeaseCtr();
	}

	public void start_lease_menu()
	{
		boolean exit = false;
		boolean is_manager = !(CurrentAccount.give_rank().equals("employee"));
		while (!(exit))
		{
			int choice = write_lease_menu(is_manager);
			if (is_manager)
			{
				switch (choice)
				{
					case 1:
						create_lease();
						break;
					case 2:
						close_lease();
						break;
					case 3:
						print_lease();
						break;
					case 4:
						print_open_leases();
						break;
					case 5:
						print_closed_leases();
						break;
					case 6:
						add_new_machine(is_manager);
						break;
					case 7:
						manage_machines();
						break;
					case 8:
						delete_machine();
						break;
					case 9:
						print_machine();
						break;
					case 10:
						print_all_machines();
						break;
					case 11:
						manage_unfinished_machines();
						break;
					default:
						exit = true;
						break;
				}
			}
			else
			{
				switch (choice)
				{
					case 1:
						create_lease();
						break;
					case 2:
						close_lease();
						break;
					case 3:
						print_lease();
						break;
					case 4:
						print_open_leases();
						break;
					case 5:
						print_closed_leases();
						break;
					case 6:
						add_new_machine(is_manager);
						break;
					case 7:
						manage_machines();
						break;
					case 8:
						delete_machine();
						break;
					case 9:
						print_machine();
						break;
					case 10:
						print_all_machines();
						break;
					default:
						exit = true;
						break;
				}
			}

		}
		lease_ctr.save_data();
		System.out.println("\f"); // Needs checking if necessary
	}

	private int write_lease_menu(boolean is_manager)
	{
		System.out.println("\f***ACCOUNT MENU***");
		System.out.println("Press (1) to register new lease.");
		System.out.println("Press (2) to close a lease");
		System.out.println("Press (3) to display a particular lease.");
		System.out.println("Press (4) to display active leases.");
		System.out.println("Press (5) to display closed leases.");
		System.out.println("Press (6) to add new machine.");
		System.out.println("Press (7) to edit machines data.");
		System.out.println("Press (8) to delete a machine.");
		System.out.println("Press (9) to dispaly a particular machine.");
		System.out.println("Press (10) to display all machines.");
		if (is_manager)
		{
			System.out.println("Press (11) to manage unfinished machines.");
		}
		System.out.println("Press any other number to exit.");
		return int_input();
	}

	private void manage_unfinished_machines()
	{
		boolean wrong = true;
		int choice;
		while (wrong)
		{
			System.out
					.println("\fPress (1) to display all unfinished machines.");
			System.out.println("Press (2) to finish adding a machine.");
			System.out.println("Press any other number to exit.");
			choice = int_input();
			switch (choice)
			{
				case 1:
					display_unfinished_machines();
					break;
				case 2:
					finish_machine();
					break;
				default:
					wrong = false;
					break;
			}
		}
	}

	/*********************************************************** INPUT READERS **************************************************************/
	private int int_input()
	{
		int input = 0;
		boolean ok = false;
		Scanner keyboard = new Scanner(System.in);
		while (!(ok))
		{
			try
			{
				input = keyboard.nextInt();
				ok = true;
			}
			catch (Exception e)
			{
				System.out
						.println("You must provide a valid input.\nYou have to type a number");
				keyboard.nextLine();
			}
		}
		keyboard.close();
		return input;
	}

	private double double_input()
	{
		double input = 0;
		boolean ok = false;
		Scanner keyboard = new Scanner(System.in);
		while (!(ok))
		{
			try
			{
				input = keyboard.nextDouble();
				ok = true;
			}
			catch (Exception e)
			{
				System.out
						.println("You must provide a valid input.\nYou have to type a number");
				keyboard.nextLine();
			}
		}
		keyboard.close();
		return input;
	}

	private String string_input()
	{
		Scanner keyboard = new Scanner(System.in);
		String output;
		while ((output = keyboard.nextLine()).equals(""))
		{

		}
		keyboard.close();
		return output;
	}

	private String input_lease_id()
	{
		System.out
				.println("Please write the ID of a desired lease or write (0) to return.");
		String id = "" + int_input();
		return id;
	}

	private String input_machine_id()
	{
		System.out
				.println("Please write the ID of a desired machine or write (0) to return.");
		String id = "" + int_input();
		return id;
	}

	private String input_return_date()
	{
		System.out
				.println("Please write the date on which machines are to be returned.\nWrite the date in dd/mm/yyyy format.");
		String return_date = "";
		Date current_date = new Date();
		String new_return_date;
		boolean wrong = true;
		while (wrong)
		{
			return_date = string_input();
			if (return_date
					.matches("[0-9][0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9]"))
			{
				SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
				sdf.setLenient(false);
				try
				{
					Date date = sdf.parse(return_date);
					if (date.getTime() <= current_date.getTime())
					{
						System.out
								.println("Inputed date is before the date of creation of the lease.\nType a correct date:");
					}
					else
					{
						wrong = false;
					}

				}
				catch (ParseException e)
				{
					System.out
							.println("The date is incorrect, please type it again:");
				}

			}
			else
			{
				System.out
						.println("The date format is incorrect, please type it again:");
			}
		}
		return return_date;
	}

	private double input_price_per_day()
	{
		System.out
				.println("Please write the price per day of leasing of this machine:");
		return double_input();
	}

	private String input_customer_id()
	{
		System.out
				.println("Input the ID of a customer that requested a lease. Press(0) to exit.");
		String customer_id = "" + int_input();
		return customer_id;
	}

	private String input_name()
	{
		System.out.println("Please write the name of the machine:");
		return string_input();
	}

	private boolean input_check()
	{
		String input = "";
		System.out.println("Type (y) for yes and (n) for no:");
		while (!((input = string_input()).equals("y") || input.equals("n")))
		{
			System.out.println("You provided incorrect input.");
		}

		if (input.equals("y"))
		{
			return true;
		}
		return false;
	}

	/********************************************* MENU FUNCTIONS *************************************************/

	private void create_lease()
	{
		String customer_id;
		while (!(((customer_id = input_customer_id()).equals("0") || CustomerCollection
				.existing_customer(customer_id))))
		{
			System.out.println("There is no such customer.");
		}

		if (!(customer_id.equals("0")))
		{
			String return_date = input_return_date();
			ArrayList<String> ids = add_machine_to_lease();
			if (!(ids.isEmpty()))
			{
				String id = lease_ctr.create_lease(return_date, ids);
				CustomerCollection.add_lease_to_customer(customer_id, id);
			}
		}
	}

	private void close_lease()
	{
		String id;
		if (!((id = check_for_lease()).equals("0")))
		{
			if (!(lease_ctr.is_lease_closed(id)))
			{
				String state = lease_ctr.return_date_control(id);
				boolean sure = true;
				boolean recalculate_cost = false;
				if (state.equals("before"))
				{
					System.out
							.println("You are trying to close a lease which return date has not yet came.\nAre you sure you want to do this?");
					sure = input_check();
					if (sure)
					{
						System.out
								.println("Do you wish to subtract the payment for not leased days from total cost of the lease?");
						recalculate_cost = input_check();
					}
				}
				else if (state.equals("after"))
				{
					System.out
							.println("You are closing a lease after it's return date.\nDo you wish to add the payment for additional days to the total cost of the lease?");
					recalculate_cost = input_check();
				}
				if (sure)
				{
					lease_ctr.close_order(id, recalculate_cost);
					System.out.println("The leased was successfully closed!");
					wait_for_input();
				}
			}
			else
			{
				System.out.println("This lease was already closed.");
				wait_for_input();
			}

		}
	}

	private void print_lease()
	{
		String id;
		if (!((id = check_for_lease()).equals("0")))
		{
			System.out.println(lease_ctr.display_lease(id));
			wait_for_input();
		}
	}

	private void print_open_leases()
	{
		System.out.println(lease_ctr.display_open_leases());
		wait_for_input();
	}

	private void print_closed_leases()
	{
		System.out.println(lease_ctr.display_closed_leases());
		wait_for_input();
	}

	private void add_new_machine(boolean is_manager)
	{
		String name = input_name();
		double price_per_day = 0;
		if (is_manager)
		{
			price_per_day = input_price_per_day();
		}

		if (lease_ctr.add_machine(name, price_per_day))
		{
			System.out.println("The machine was successfully added!");
		}
		else
		{
			System.out.println("The machine was not added.");
		}
		wait_for_input();
	}

	private void manage_machines()
	{
		String id;
		if (!((id = check_for_machine()).equals("0")))
		{
			String name = input_name();
			double price_per_day = input_price_per_day();
			lease_ctr.edit_machine(id, name, price_per_day);
		}
	}

	private void delete_machine()
	{
		String id;
		if (!((id = check_for_machine()).equals("0")))
		{
			if (lease_ctr.is_machine_leased(id))
			{
				System.out
						.println("This machine is currently leased. You cannot delete leased machines.");
				wait_for_input();
			}
			else
			{
				if (lease_ctr.delete_machine(id))
				{
					System.out.println("The machine was successfully deleted");
					wait_for_input();
				}
				else
				{
					System.out.println("The machine was not deleted.");
					wait_for_input();
				}
			}
		}
	}

	private void print_machine()
	{
		String id;
		if (!((id = check_for_machine()).equals("0")))
		{
			if (lease_ctr.is_machine_unfinished(id))
			{
				System.out
						.println("The inputting of machine into the system has not been finished.\nThe price of the lease of the machine still needs to be inserted.");
			}
			System.out.println(lease_ctr.display_machine(id));
			wait_for_input();
		}
	}

	private void print_all_machines()
	{
		System.out.println(lease_ctr.display_all_machines());
		wait_for_input();
	}

	private void display_unfinished_machines()
	{
		System.out.println(lease_ctr.display_unfinished_machines());
		wait_for_input();
	}

	private void finish_machine()
	{
		String id;
		while (!((id = check_for_machine()).equals("0") || lease_ctr
				.is_machine_unfinished(id)))
		{
			System.out.println("This machine does not require finishing.");
		}
		if (!(id.equals("0")))
		{
			lease_ctr.finish_machine(id, input_price_per_day());
		}
	}

	private ArrayList<String> add_machine_to_lease()
	{
		ArrayList<String> ids = new ArrayList<>();
		boolean exit = false;
		String id;
		while (!(exit))
		{
			System.out.println("\fPress (1) to add new machine to lease.");
			System.out.println("Press (2) to finish.");
			int choice = int_input();
			if (choice == 1)
			{
				id = check_for_machine();
				if (!(lease_ctr.is_machine_unfinished(id)))
				{
					if (!(id.equals("0")))
					{
						if (!(ids.contains(id)))
						{
							if (!(lease_ctr.is_machine_leased(id)))
							{
								if (ids.add(id))
								{
									System.out
											.println("The machine was successfully added!\n");
									wait_for_input();
								}
							}
							else
							{
								System.out
										.println("The machine is unavailable. \nIt has already been leased.");
								wait_for_input();
							}
						}
						else
						{
							System.out
									.println("You already added this machine.");
							wait_for_input();
						}
					}
				}
				else
				{
					System.out
							.println("The input of this machine into the system has not yet been finished.\nYou cannot add unfinished machines into leases.");
					wait_for_input();
				}
			}
			else if (choice == 2)
			{
				boolean do_i = false;
				if (ids.isEmpty())
				{
					System.out
							.println("You haven't added any machines and therefore the lease will not be created. \nDo you wish to add any machines?");
					do_i = input_check();
				}
				if (!(do_i))
				{
					exit = true;
				}
			}
		}
		return ids;
	}

	private void wait_for_input()
	{
		System.out.println("\nPRESS ENTER TO CONTINUE\n");
		Scanner keyboard = new Scanner(System.in);
		keyboard.nextLine();
		keyboard.close();
	}

	private String check_for_machine()
	{
		String id;
		while (!(lease_ctr.is_such_machine_id(id = input_machine_id())))
		{
			if (id.equals("0"))
			{
				return id;
			}
			System.out.println("There is no machine with this ID");
		}
		return id;
	}

	private String check_for_lease()
	{
		String id;
		while (!(lease_ctr.is_such_lease_id(id = input_lease_id())))
		{
			if (id.equals("0"))
			{
				return id;
			}
			System.out.println("There is no lease with this ID:");
		}
		return id;
	}

}
